/*
 * File         : cym_def.h
 * Version      : 0.6.0
 * Author       : Vincent Cheung
 * Date         : Sept. 23, 2013
 * Description  : This file contains all the defination for this project.
 *
 * Copyright (C) 2013, CYM Co., Ltd.
 *
 * Change Logs  :
 * Date                 Author          Notes
 * Sept. 23, 2013       Vincent         first version
 * Oct. 24, 2013        Vincent         add net device and package structure
 * Oct. 30, 2013        Vincent         add CYM_TIMER_FLAG_HARD_TIMER,
 *                                      CYM_TIMER_FLAG_HARD_TIMER and
 *                                      CYM_TIMER_FLAG_HIGH_PREC_TIMER,
 *                                      move CYM_USING_16BIT_CPU and 
 *                                      CYM_NAME_MAX to cym_config.h
 * Oct. 31, 2013        Vincent         change data[8] to data[CYM_DATA_LENGTH]
 * Nov. 05, 2013        Vincent         change data type definations
 * Nov. 06, 2013        Vincent         fix timer flag bugs
 * Nov. 12, 2013        Vincent         add char_t
 * Nov. 13, 2013        Vincent         add sync macors
 * Nov. 14, 2013        Vincent         add half hz support
 * Nov. 19, 2013        Vincent         add key support
 *
 */

#ifndef __CYM_DEF_H__
#define __CYM_DEF_H__

#include "cym_config.h"

/**
 * @addtogroup BasicDef
 */

/*@{*/

/* basic data type definations */
typedef signed char             sint8_t;        /**< 8bit integer type */
typedef signed int              sint16_t;       /**< 16bit integer type */
typedef signed long             sint32_t;       /**< 32bit integer type */
typedef unsigned char           uint8_t;        /**< 8bit unsigned integer type */
typedef unsigned int            uint16_t;       /**< 16bit unsigned integer type */
typedef unsigned long           uint32_t;       /**< 32bit unsigned interger type */
typedef int                     bool_t;         /**< boolean type */
typedef char                    char_t;         /**< character type */

/* 16 bit CPU */
typedef uint32_t                utick_t;        /**< type for tick number */
typedef uint32_t                utime_t;        /**< type for time stamp */
typedef sint16_t                serr_t;         /**< type for error number */
typedef uint16_t                usize_t;        /**< type for size */
typedef uint16_t                uoff_t;         /**< type for offset */

/* maximum value of base type */
#define CYM_UINT8_MAX           0xff            /**< maximum number of uint8 */
#define CYM_UINT16_MAX          0xffff          /**< maximum number of uint16 */
#define CYM_UINT32_MAX          0xffffffff      /**< maximum number of uint32 */
#define CYM_TICK_MAX            CYM_UINT32_MAX  /**< maximum number of tick */

/* boolean type definations */
#define CYM_FALSE               0               /**< boolean false */
#define CYM_TRUE                1               /**< boolean true */

/**
 * @def CYM_NULL
 * null type definations 
 */
#define CYM_NULL                (0)

/*@}*/

/**
 * @addtogroup Error
 */

/*@{*/

/* error code definations */
#define CYM_EOK                 0               /**< there is no error */
#define CYM_ERROR               1               /**< a error happens */
#define	CYM_EBUSY               2               /**< busy */

/*@}*/

/**
 * @addtogroup BasicDef
 */

/*@{*/

/**
 * list structure
 */
struct list_node 
{
        struct list_node *next;                 /**< point to next node */
        struct list_node *prev;                 /**< point to previous node */
};
typedef struct list_node list_t;                /**< type for list type */

/**
 * kernel object structure
 */
struct k_object
{
        list_t         list;                    /**< list node of kernel object */
        char           name[CYM_NAME_MAX];      /**< name of kernel object */
        uint16_t       flag;                    /**< flag of kernel object */
};

/*@}*/

/* all the sync macros */
#define CYM_HALF_HZ_SYNC                0       /**< half Hz */
#define CYM_1HZ_SYNC                    1       /**< 1Hz */
#define CYM_2HZ_SYNC                    2       /**< 2Hz */

#define CYM_HALF_HZ_SYNC_MAX            500     /**< half hz max sync time(ms) */
#define CYM_1HZ_SYNC_MAX                250     /**< 1Hz max sync time(ms) */
#define CYM_2HZ_SYNC_MAX                125     /**< 2Hz max sync time(ms) */

/**
 * synch information
 */
struct sync_info
{
        bool_t          sync_flag;              /**< flag of current time */
        utime_t         pass_time;              /**< the time(ms) since last rotation */
};

/**
 * @addtogroup TimerAndClock
 */

/*@{*/

/* all the flags of timer & clock */
#define CYM_TIMER_FLAG_DEACTIVATED      0x00    /**< timer is deactivated */
#define CYM_TIMER_FLAG_ACTIVATED        0x01    /**< timer is activated */

#define CYM_TIMER_FLAG_ONE_SHOT         0x02    /**< one shot timer */
#define CYM_TIMER_FLAG_PERIODIC         0x04    /**< periodic timer */

#define CYM_TIMER_FLAG_HARD_TIMER       0x10    /**< hardware timer */
#define CYM_TIMER_FLAG_SOFT_TIMER       0x20    /**< software timer */
#define CYM_TIMER_FLAG_HIGH_PREC_TIMER  0x40    /**< high precision hardware timer */

#define CYM_TIMER_CTRL_SET_TIME         0x00    /**< set time control command */
#define CYM_TIMER_CTRL_GET_TIME         0x01    /**< get time control command */
#define CYM_TIMER_CTRL_SET_ONE_SHOT     0x02    /**< set timer to one shot */
#define CYM_TIMER_CTRL_SET_PERIODIC     0x04    /**< set timer to periodic */

/**
 * timer structure
 */
struct k_timer
{
        struct k_object         parent;         /**< inherit from object */

        list_t                  list;           /**< the node of timer list */

        void (*timeout_func)(void *parameter);  /**< timeout callback function */
        void                   *parameter;      /**< parameter of timeout callback function */

        utick_t                 interval_tick;  /**< interval tick */
        utick_t                 timeout_tick;   /**< timeout tick */
};
typedef struct k_timer         *p_timer_t;      /**< type for timer type */

/*@}*/

/**
 * @addtogroup Device
 */

/*@{*/

/* all the flags of device */
#define CYM_DEVICE_FLAG_DEACTIVATED     0x000   /**< device is not initialized */
#define CYM_DEVICE_FLAG_ACTIVATED       0x001   /**< device is activated */

#define CYM_DEVICE_FLAG_RDONLY          0x010   /**< read only */
#define CYM_DEVICE_FLAG_WRONLY          0x020   /**< write only */
#define CYM_DEVICE_FLAG_RDWR            0x040   /**< read and write */

#define CYM_DEVICE_FLAG_INT_RX          0x100   /**< INT mode on RX */
#define CYM_DEVICE_FLAG_INT_TX          0x200   /**< INT mode on TX */

#define CYM_DEVICE_OFLAG_CLOSE          0x000   /**< device is closed */
#define CYM_DEVICE_OFLAG_RDONLY         0x010   /**< read only access */
#define CYM_DEVICE_OFLAG_WRONLY         0x020   /**< write only access */
#define CYM_DEVICE_OFLAG_RDWR           0x040   /**< read and write */
#define CYM_DEVICE_OFLAG_OPEN           0x080   /**< device is opened */

typedef struct k_device *p_device_t;            /**< type for device */
/**
 * device structure
 */
struct k_device
{
        struct k_object         parent;         /**< inherit from object */

        uint16_t                open_flag;      /**< device open flag */

        /* device callback function */
        serr_t         (*rx_indicate)(p_device_t dev, usize_t size);
        serr_t         (*tx_complete)(p_device_t dev, void *buffer);

        /* device interface */
        serr_t         (*init)(p_device_t dev);
        serr_t         (*open)(p_device_t dev, uint16_t oflag);
        serr_t         (*close)(p_device_t dev);
        usize_t        (*read)(p_device_t dev, uoff_t pos, void *buffer, usize_t size);
        usize_t        (*write)(p_device_t dev, uoff_t pos, const void *buffer, usize_t size);
        serr_t         (*control)(p_device_t dev, uint8_t cmd, void *arg);

        void            *user_data;             /**< device private data */
};

/*@}*/

#ifdef CYM_USING_NET

/**
 * @addtogroup Net
 */

/*@{*/

/**
 * net package structure
 */
struct net_package
{
        uint32_t                id;                     /**< ID */
        uint8_t                 dlc;                    /**< data length code */
        uint8_t                 data[CYM_DATA_LENGTH];  /**< data field */
};

/**
 * net device structure
 */
struct net_device
{
        struct k_device         parent;                 /**< inherit from device */

        /* net device interface */
        struct net_package    *(*net_rx)(p_device_t dev);
        serr_t                 (*net_tx)(p_device_t dev, struct net_package *pack);
};
typedef struct net_device      *p_net_device_t;         /**< type for net device */

/*@}*/

#endif  /* CYM_USING_NET */

#ifdef CYM_USING_KEY

/**
 * @addtogroup Key
 */

/*@{*/

/**
 * The enum describe value of the key.
 */
enum key_val
{
        KEY_NULL = 0,
        KEY_SHORT_PRESS,
        KEY_LONG_PRESS,
        KEY_LONG_LONG_PRESS,
};

/**
 * key state structure
 */
struct key_state
{
        list_t          list;                   /**< the node of key list */

        uint8_t         key;                    /**< the key code */
        uint8_t         key_value;              /**< the key value */
        uint8_t         pressed_flag;           /**< the pressed flag */

        uint16_t        count;                  /**< the filter count */
        uint16_t        duration;               /**< duration since the key is pressed */
};

/**
 * key listener structure
 */
struct key_listener
{
        list_t          list;                   /**< the node of key listener list */

        /* key interface */
        void (*on_key_down)(struct key_state *sate);
        void (*on_key_up)(struct key_state *state);
};

/**
 * key module structure
 */
struct key_module
{
        uint16_t filter;                        /**< the filter factor */

        void (*init)(void);                     /**< initialize */
        bool_t (*is_pressed)(uint8_t key);      /**< the pressed detector */
};

/*@}*/

#endif  /* CYM_USING_KEY */

#endif  /* __CYM_DEF_H__ */